﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

namespace DAUserControl
{
    public partial class DAForm : Form
    {
        public DAForm()
        {
            InitializeComponent();
        }

        #region --- Declare Variables ---
            private double idleOpacity = 0.5; //how opaque it is when the mouse is not on it
            private double fadeRate = 0.050; //how fast the form fades in/out

            public static int FormHeight = 550;
            public static int FormWidth = 1000;

            private const int CS_DROPSHADOW = 0x20000;

            Thread fadeIn;
            Thread fadeOut;

            Point lastPoint;
            
        #endregion --- Declare Variables ---

        #region --- Create a Drop Shadow ---
            protected override CreateParams CreateParams
            {
                get
                {
                    const int CS_DROPSHADOW = 0x20000;
                    CreateParams param = base.CreateParams;
                    param.ClassStyle += CS_DROPSHADOW;
                    return param;
                }
            }
        #endregion --- Create a Drop Shadow ---

        #region --- Effect Method ---
            
            private delegate void ChangeOpacityDelegate(double value);
            private void ChangeOpacity(double value)
            {
                if (this.InvokeRequired)
                {
                    ChangeOpacityDelegate del = new ChangeOpacityDelegate(ChangeOpacity);
                    object[] parameters = { value };

                    this.Invoke(del, value);
                }
                else
                {
                    this.Opacity = value;
                }
            }

            private void FadeIn()
            {
                for (double i = this.Opacity; i <= 1; i += fadeRate)
                {
                    ChangeOpacity(i);
                }

                if (this.Opacity != 1.00)
                    ChangeOpacity(1.00);
            }

            private void FadeOut()
            {
                for (double i = this.Opacity; i >= idleOpacity; i -= fadeRate)
                {
                    ChangeOpacity(i);
                }

                if (this.Opacity != idleOpacity)
                    ChangeOpacity(idleOpacity);
            }
      
            private void DAForm_Load(object sender, EventArgs e)
            {
                this.TransparencyKey = Color.DarkGray; //Prevent flicker from opacity change by forcing
                //The form to be layered now

                this.Opacity = idleOpacity;

                //Prepare the fade in/out threads that will be called later
                ThreadStart fadeInStart = new ThreadStart(FadeIn);
                fadeIn = new Thread(fadeInStart);

                ThreadStart fadeOutStart = new ThreadStart(FadeOut);
                fadeOut = new Thread(fadeOutStart);
            }

            private void DAForm_Paint(object sender, PaintEventArgs e)
            {
                //Draw a solid backgroud with a thin border
                Graphics draw = e.Graphics;
                draw.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                Rectangle area = this.ClientRectangle;
                area.Width -= 1;
                area.Height -= 1;

                Pen outline = new Pen(Color.DodgerBlue, 3);

                //draw.FillRectangle(Brushes.LightYellow, this.ClientRectangle); //Background
                draw.DrawRectangle(outline, area); //Border

                outline.Dispose();
            }

        #endregion --- Effect Method ---

        #region --- Move Form  Method---
            private void DAForm_MouseDown(object sender, MouseEventArgs e)
            {
                lastPoint = new Point(e.X, e.Y); 
            }

            private void DAForm_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
                {
                    this.Left += e.X - lastPoint.X;
                    this.Top += e.Y - lastPoint.Y;
                }
            }
        #endregion --- Move Form Method ---

        #region --- Mousing ---
            private void DAForm_MouseEnter(object sender, EventArgs e)
            {
                //Cancel running fading threads to avoid overflowing the stack
                if (fadeIn.ThreadState == ThreadState.Running)
                    fadeIn.Abort();

                if (fadeOut.ThreadState == ThreadState.Running)
                    fadeOut.Abort();

                //Begin fading in
                ThreadStart fadeInStart = new ThreadStart(FadeIn);
                fadeIn = new Thread(fadeInStart);

                fadeIn.Start();
            }

            private void DAForm_MouseLeave(object sender, EventArgs e)
            {
                //If the mouse goes over a control in the form, the MouseLeave event (this one)
                //is called. We do not want to fade out if the mouse is still pointing at something
                //inside the form. This is a quick dirty fix, just check if the mouse is within
                //the form's bounds
                if (this.Bounds.Contains(Cursor.Position)) return;

                //Cancel running fading threads to avoid overflowing the stack
                if (fadeIn.ThreadState == ThreadState.Running)
                    fadeIn.Abort();

                if (fadeOut.ThreadState == ThreadState.Running)
                    fadeOut.Abort();

                //Begin fading out
                ThreadStart fadeOutStart = new ThreadStart(FadeOut);
                fadeOut = new Thread(fadeOutStart);

                fadeOut.Start();
            }
        #endregion --- Mousing ---
    }
}
